module;
#include <limits>
export module Code_19_7_1;

//[1]
// primary template: yield the second argument by default and relyon// a partial specialization to yield the third argument
// if COND is false
template<bool COND, typename TrueType, typename FalseType>
struct IfThenElseT 
{
    using Type = TrueType;
};
//[1]
// partial specialization: false yields third argument
template<typename TrueType, typename FalseType>
struct IfThenElseT<false, TrueType, FalseType> 
{
    using Type = FalseType;
};

//[1]
template<bool COND, typename TrueType, typename FalseType>
using IfThenElse = typename IfThenElseT<COND, TrueType, FalseType>::Type;

//[2]
template<auto N>
struct SmallestIntT 
{
    using Type = 
        typename IfThenElseT<
                            N <= std::numeric_limits<char> ::max(), 
                            char,
                            typename IfThenElseT<
                                                N <= std::numeric_limits<short> ::max(),
                                                short,
                                                typename IfThenElseT<
                                                                    N <= std::numeric_limits<int> ::max(), 
                                                                    int,
                                                                    typename IfThenElseT<
                                                                                        N <= std::numeric_limits<long>::max(), 
                                                                                        long,
                                                                                        typename IfThenElseT<
                                                                                                            N <= std::numeric_limits<long long>::max(), 
                                                                                                            long long, //then
                                                                                                            void //fallback
                                                                                                            >::Type
                                                                                        >::Type
                                                                    >::Type
                                                >::Type
                            >::Type;
};


export
namespace Code_19_7_1 {

    void run()
    {

    }
}
